package app

import (
	"database/sql"
	"fmt"
	"time"
	"uni-core/pkg/tools"

	"fyne.io/fyne/v2"
	"fyne.io/fyne/v2/container"
	"fyne.io/fyne/v2/dialog"
	"fyne.io/fyne/v2/layout"
	"fyne.io/fyne/v2/storage"
	"fyne.io/fyne/v2/theme"
	"fyne.io/fyne/v2/widget"
	"gitee.com/MM-Q/fastlog"
	"github.com/jmoiron/sqlx"
)

// dataManageTabUI 数据管理选项卡UI
func dataManageTabUI(w fyne.Window, db *sqlx.DB, log *fastlog.FastLog) *container.TabItem {
	// 创建一个边框容器
	borderContainer := container.NewBorder(
		nil,                         // 顶部
		nil,                         // 底部
		nil,                         // 左侧
		nil,                         // 右侧
		buttonContainer(w, db, log), // 中心
	)

	// 创建一个标签页项
	tabItem := container.NewTabItem("数据管理", borderContainer)

	return tabItem
}

// buttonContainer 返回按钮容器
func buttonContainer(w fyne.Window, db *sqlx.DB, log *fastlog.FastLog) *fyne.Container {
	// 导出数据到csv按钮
	exportCSVButton := returnExportCSVButton(w, db, log)

	// 设置按钮重要性
	exportCSVButton.Importance = widget.HighImportance

	// 设置导出按钮图标
	exportCSVButton.SetIcon(theme.DocumentSaveIcon())

	// 导入csv到数据库按钮
	importCSVButton := returnImportCSVButton(w, db, log)

	// 设置按钮重要性
	importCSVButton.Importance = widget.HighImportance

	// 设置导入按钮图标
	importCSVButton.SetIcon(theme.FolderOpenIcon())

	// 导出数据到JSON按钮
	exportJSONButton := returnExportJSONButton(w, db, log)

	// 设置按钮重要性
	exportJSONButton.Importance = widget.HighImportance

	// 设置导出按钮图标
	exportJSONButton.SetIcon(theme.DocumentSaveIcon())

	// 导入JSON到数据库按钮
	importJSONButton := returnImportJSONButton(w, db, log)

	// 设置按钮重要性
	importJSONButton.Importance = widget.HighImportance

	// 设置导入按钮图标
	importJSONButton.SetIcon(theme.FolderOpenIcon())

	// 创建清空数据按钮
	clearDataButton := widget.NewButton("清空数据", func() {
		// 显示确认对话框
		dialog.ShowConfirm("确认清空", "确定要清空所有密码记录吗？此操作不可恢复！", func(confirmed bool) {
			if confirmed {
				// 检查数据库是否为空
				var count int
				if err := db.Get(&count, "SELECT COUNT(*) FROM pswd_data"); err != nil {
					dialog.ShowError(fmt.Errorf("查询记录数失败: %s", err), w)
					return
				}

				// 如果数据库为空，则显示提示信息
				if count == 0 {
					dialog.ShowInformation("操作成功", "当前没有存储任何记录", w)
					return
				}

				// 执行清空操作
				if _, err := db.Exec("DELETE FROM pswd_data"); err != nil {
					dialog.ShowError(fmt.Errorf("清空数据失败: %s", err), w)
					return
				}
				// 刷新全局数据
				queryPswdData(db, log)
				dialog.ShowInformation("操作成功", "所有密码记录已清空", w)
			}
		}, w)
	})
	clearDataButton.Importance = widget.HighImportance
	clearDataButton.SetIcon(theme.DeleteIcon())

	// 创建数据统计按钮
	statsButton := widget.NewButton("数据统计", func() {
		var count int
		if err := db.Get(&count, "SELECT COUNT(*) FROM pswd_data"); err == sql.ErrNoRows {
			// 数据库为空
			dialog.ShowInformation("数据统计", "当前没有存储任何记录", w)
			return
		} else if err != nil {
			dialog.ShowError(fmt.Errorf("查询记录数失败: %s", err), w)
			return
		}

		dialog.ShowInformation("数据统计", fmt.Sprintf("当前共存储了%d条记录", count), w)
	})
	statsButton.Importance = widget.HighImportance
	statsButton.SetIcon(theme.InfoIcon())

	// 创建现代化卡片式布局
	card1 := container.NewVBox(
		widget.NewLabelWithStyle("CSV 操作", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}),
		container.NewPadded(exportCSVButton),
		container.NewPadded(importCSVButton),
	)
	card1 = container.NewPadded(card1)

	card2 := container.NewVBox(
		widget.NewLabelWithStyle("JSON 操作", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}),
		container.NewPadded(exportJSONButton),
		container.NewPadded(importJSONButton),
	)
	card2 = container.NewPadded(card2)

	card3 := container.NewVBox(
		widget.NewLabelWithStyle("扩展功能", fyne.TextAlignCenter, fyne.TextStyle{Bold: true}),
		container.NewPadded(clearDataButton),
		container.NewPadded(statsButton),
	)
	card3 = container.NewPadded(card3)

	buttonContainer := container.NewHBox(
		layout.NewSpacer(),
		card1,
		layout.NewSpacer(),
		card2,
		layout.NewSpacer(),
		card3,
		layout.NewSpacer(),
	)

	// 设置按钮颜色 - 与密码管理界面风格一致
	exportCSVButton.Importance = widget.HighImportance
	importCSVButton.Importance = widget.HighImportance
	exportJSONButton.Importance = widget.HighImportance
	importJSONButton.Importance = widget.HighImportance
	clearDataButton.Importance = widget.HighImportance
	statsButton.Importance = widget.HighImportance

	return buttonContainer
}

// returnExportCSVButton 返回导出csv按钮
// 参数：
// w fyne.Window - 窗口
// db *sqlx.DB - 数据库连接
// log *fastlog.FastLog - 日志
// 返回：
// \*widget.Button - 导出csv按钮
func returnExportCSVButton(w fyne.Window, db *sqlx.DB, log *fastlog.FastLog) *widget.Button {
	return widget.NewButton("导出CSV", func() {
		// 创建现代化导出选项对话框
		subtitle := widget.NewLabelWithStyle("请选择导出选项:", fyne.TextAlignCenter, fyne.TextStyle{Italic: true})
		encrypted := widget.NewRadioGroup([]string{"加密", "明文"}, func(s string) {})
		encrypted.SetSelected("加密")
		encrypted.Horizontal = true // 水平布局

		// 创建卡片式对话框内容
		card := container.NewVBox(
			container.NewHBox(layout.NewSpacer(), subtitle, layout.NewSpacer()),
			layout.NewSpacer(),
			container.NewHBox(layout.NewSpacer(), encrypted, layout.NewSpacer()),
			layout.NewSpacer(),
		)
		card = container.NewPadded(card)
		card.Resize(fyne.NewSize(400, 200))

		// 显示自定义对话框
		dialog.ShowCustomConfirm("导出CSV", "确认", "取消", card, func(confirmed bool) {
			if !confirmed {
				return
			}

			// 获取加密选项 true为加密, false为解密
			decrypt := encrypted.Selected == "明文"

			// 创建一个文件选择对话框
			fd := dialog.NewFileSave(func(writer fyne.URIWriteCloser, err error) {
				// 检查错误
				if err != nil {
					dialog.ShowError(err, w)
					return
				}

				// 检查文件写入器
				if writer == nil {
					return
				}
				defer writer.Close() // 确保文件写入器关闭

				// 获取密码数据
				queryPswdData(db, log)

				// 导出数据到csv
				if exportErr := tools.ExportToCSV(globalPswdData, writer, decrypt); exportErr != nil {
					dialog.ShowError(fmt.Errorf("导出数据时发生了错误: %s", exportErr), w)
					return
				}

				// 显示成功提示
				dialog.ShowInformation("导出成功", fmt.Sprintf("密码数据已成功导出到 %s", writer.URI().Path()), w)
			}, w)

			// 设置文件选择对话框的默认文件名
			fd.SetFileName("password_data.csv")

			// 设置文件选择对话框的过滤器
			fd.SetFilter(storage.NewExtensionFileFilter([]string{".csv"}))

			// 设置文件选择对话框的样式
			fd.Resize(fyne.NewSize(800, 600))
			fd.SetDismissText("取消")
			fd.SetConfirmText("保存")

			// 如果查询密码为空
			if len(globalPswdData) == 0 {
				dialog.ShowError(fmt.Errorf("没有密码记录可以导出"), w)
				return
			}

			// 显示带有加载动画的文件选择对话框
			loading := dialog.NewCustomWithoutButtons("加载中...", widget.NewProgressBarInfinite(), w)
			fyne.Do(func() {
				loading.Show()

				// 延迟关闭加载动画并显示对话框
				time.AfterFunc(500*time.Millisecond, func() {
					fyne.Do(func() {
						loading.Hide()
						fd.Show()
					})
				})
			})
		}, w)
	})
}

// returnImportCSVButton 返回导入CSV按钮
func returnImportCSVButton(w fyne.Window, db *sqlx.DB, log *fastlog.FastLog) *widget.Button {
	return widget.NewButton("导入CSV", func() {
		// 创建一个文件选择对话框
		fd := dialog.NewFileOpen(func(reader fyne.URIReadCloser, err error) {
			// 检查错误
			if err != nil {
				dialog.ShowError(err, w)
				return
			}

			// 检查文件读取器
			if reader == nil {
				return
			}
			defer reader.Close()

			// 导入csv
			var count int
			if err := tools.ImportFromCSVPwsdData(reader.URI().Path(), db, &count); err != nil {
				dialog.ShowError(fmt.Errorf("导入数据时发生了错误: %s", err), w)
				return
			}

			// 刷新密码数据
			queryPswdData(db, log)

			dialog.ShowInformation("导入成功", fmt.Sprintf("导入数据成功, 共导入%d条数据", count), w)
		}, w)

		// 设置文件选择对话框的过滤器
		fd.SetFilter(storage.NewExtensionFileFilter([]string{".csv"}))

		// 设置文件选择对话框的样式
		fd.Resize(fyne.NewSize(800, 600))
		fd.SetDismissText("取消")
		fd.SetConfirmText("选择")

		// 显示带有加载动画的文件选择对话框
		loading := dialog.NewCustomWithoutButtons("加载中...", widget.NewProgressBarInfinite(), w)
		fyne.Do(func() {
			loading.Show()

			// 延迟关闭加载动画并显示对话框
			time.AfterFunc(500*time.Millisecond, func() {
				fyne.Do(func() {
					loading.Hide()
					fd.Show()
				})
			})
		})
	})
}

// returnExportJSONButton 返回导出JSON按钮
func returnExportJSONButton(w fyne.Window, db *sqlx.DB, log *fastlog.FastLog) *widget.Button {
	return widget.NewButton("导出JSON", func() {
		// 创建现代化导出选项对话框
		subtitle := widget.NewLabelWithStyle("请选择导出选项:", fyne.TextAlignCenter, fyne.TextStyle{Italic: true})
		encrypted := widget.NewRadioGroup([]string{"加密", "明文"}, func(s string) {})
		encrypted.SetSelected("加密")
		encrypted.Horizontal = true // 水平布局

		// 创建卡片式对话框内容
		card := container.NewVBox(
			container.NewHBox(layout.NewSpacer(), subtitle, layout.NewSpacer()),
			layout.NewSpacer(),
			container.NewHBox(layout.NewSpacer(), encrypted, layout.NewSpacer()),
			layout.NewSpacer(),
		)
		card = container.NewPadded(card)
		card.Resize(fyne.NewSize(400, 200))

		// 显示自定义对话框
		dialog.ShowCustomConfirm("导出JSON", "确认", "取消", card, func(confirmed bool) {
			if !confirmed {
				return
			}
			// 获取加密选项 true为加密, false为解密
			decrypt := encrypted.Selected == "明文"

			// 创建一个文件选择对话框
			fd := dialog.NewFileSave(func(writer fyne.URIWriteCloser, err error) {
				// 检查错误
				if err != nil {
					dialog.ShowError(err, w)
					return
				}

				// 检查文件写入器
				if writer == nil {
					return
				}
				defer writer.Close()

				// 获取密码数据
				queryPswdData(db, log)

				// 导出数据到JSON
				if exportErr := tools.ExportToJSON(globalPswdData, writer, decrypt); exportErr != nil {
					dialog.ShowError(fmt.Errorf("导出数据时发生了错误: %s", exportErr), w)
					return
				}

				// 显示成功提示
				dialog.ShowInformation("导出成功", fmt.Sprintf("密码数据已成功导出到 %s", writer.URI().Path()), w)
			}, w)

			// 设置文件选择对话框的默认文件名
			fd.SetFileName("password_data.json")

			// 设置文件选择对话框的过滤器
			fd.SetFilter(storage.NewExtensionFileFilter([]string{".json"}))

			// 设置文件选择对话框的样式
			fd.Resize(fyne.NewSize(800, 600))
			fd.SetDismissText("取消")
			fd.SetConfirmText("保存")

			// 如果查询密码为空
			if len(globalPswdData) == 0 {
				dialog.ShowError(fmt.Errorf("没有密码记录可以导出"), w)
				return
			}

			// 显示带有加载动画的文件选择对话框
			loading := dialog.NewCustomWithoutButtons("加载中...", widget.NewProgressBarInfinite(), w)
			fyne.Do(func() {
				loading.Show()

				// 延迟关闭加载动画并显示对话框
				time.AfterFunc(500*time.Millisecond, func() {
					fyne.Do(func() {
						loading.Hide()
						fd.Show()
					})
				})
			})
		}, w)
	})
}

// returnImportJSONButton 返回导入JSON按钮
func returnImportJSONButton(w fyne.Window, db *sqlx.DB, log *fastlog.FastLog) *widget.Button {
	return widget.NewButton("导入JSON", func() {
		// 创建一个文件选择对话框
		fd := dialog.NewFileOpen(func(reader fyne.URIReadCloser, err error) {
			// 检查错误
			if err != nil {
				dialog.ShowError(err, w)
				return
			}

			// 检查文件读取器
			if reader == nil {
				return
			}
			defer reader.Close()

			// 导入JSON
			var count int
			if err := tools.ImportFromJSONPwsdData(reader.URI().Path(), db, &count); err != nil {
				dialog.ShowError(fmt.Errorf("导入数据时发生了错误: %s", err), w)
				return
			}

			// 刷新密码数据
			queryPswdData(db, log)

			dialog.ShowInformation("导入成功", fmt.Sprintf("导入数据成功, 共导入%d条数据", count), w)
		}, w)

		// 设置文件选择对话框的过滤器
		fd.SetFilter(storage.NewExtensionFileFilter([]string{".json"}))

		// 设置文件选择对话框的样式
		fd.Resize(fyne.NewSize(800, 600))
		fd.SetDismissText("取消")
		fd.SetConfirmText("选择")

		// 显示带有加载动画的文件选择对话框
		loading := dialog.NewCustomWithoutButtons("加载中...", widget.NewProgressBarInfinite(), w)
		fyne.Do(func() {
			loading.Show()

			// 延迟关闭加载动画并显示对话框
			time.AfterFunc(500*time.Millisecond, func() {
				fyne.Do(func() {
					loading.Hide()
					fd.Show()
				})
			})
		})
	})
}
